{ 此篇為備忘錄純紀錄使用 }
🚀 #什麼是 MQTT?
MQTT 是一種專為物聯網(IoT)設計的輕量級通訊協議。
它讓各種裝置(感測器、手機、伺服器)能用很少的流量就互相傳訊息。
🔸 三個角色:
Publisher(發布者):發送訊息到某個主題(Topic)
→ 例:line/test
Broker(代理伺服器):負責轉送訊息給訂閱者
→ EMQX 就是 Broker
Subscriber(訂閱者):訂閱主題,接收訊息
🧠 #什麼是 EMQX?
EMQX (第三方 MQTT Broker 軟體供應商) 是一個高性能的 MQTT Broker(訊息中樞)。
它可以同時連線上百萬台裝置,接收訊息、處理規則,並轉發到外部系統。
🔹 #EMQX 能做什麼?
支援 MQTT、WebSocket、HTTP
透過 規則引擎(Rule Engine):
把訊息轉送到 資料庫
呼叫 HTTP / Node.js API
或整合到 LINE、雲端平台 等服務
🧩 簡單理解:
MQTT 是傳訊協議,
EMQX 是接收與轉發訊息的中樞。
它就像「郵局」,負責讓發訊者與收訊者順利溝通。
#❓#為什麼要使用 MQTT?
因為 MQTT 是專為「低延遲、低流量」設計的通訊協議,非常適合用在物聯網(IoT)或需要即時通知的系統。
✅ 使用 MQTT 的好處:
輕量快速:傳輸資料只需要很少的頻寬
即時推送:裝置一有新資料就能馬上發出去,不用輪詢
穩定可靠:有 QoS 等級可選,確保訊息有送達
支援離線設備:裝置連回來還能收到離線時的訊息(保留訊息 + LWT)
跨平台相容性高:支援各種裝置與語言(手機、樹莓派、微控制器、伺服器)
#第一步驟 到三方 EMQX 建立 broker ( 也可以自建,這邊演示透過三方免費額度)
(1)https://www.emqx.com/en
(2).紀錄好這些信息稍等node js 連接時會使用
(3).這裡我們建立一個新的connector
(4).這裡我們選擇http
(5).填寫URL,***注意這裡是第一個容易出錯的點,這裡填的是主域名即可不需要整個完整api路逕都填上
例如 : https://mqtt.mydomain.com/sendline <====不可以這樣填 只需要填寫 https://mqtt.mydomain.com
(6).我們回到 Data Integration
選擇 New Rules建立接收訂閱參數規則
(7).填上規則
這裡前面的 to ,跟 message 就是等下對主題發送的參數 , line/test就是主題(你可以自行定義)
(8).接著剛剛的頁面往下捲動一點 點擊 New Action(sink)
(9).選擇Connector
(10).填上path,**注意這裡是第二個容易出錯的地方,
如果你準備的API完整路由是
https://mqtt.mydomain.com/sendline , 只需要填寫 sendline
(11).body填上要轉送給你api參數內容,這裡我的api接收是json格式
到這裡 EMXQ 設定都結束了 !~
我們來看看 node js 設定部份
(1).node js 處理連接的部份 , 將上面連接信息填上
這裡可以看到,當連接上後 我對剛剛產生的主題發送 client.publish('line/test'
const client = mqtt.connect('mqtts://f8133333.ala.asia-southeast1.emqxsl.com:8883', {
username: 'username',
password: 'xxxxxx'
});
client.on('connect', () => {
console.log('MQTT connected to EMQX server');
client.subscribe('line/test');
const msg = {
to: "U4913f670f9f1ef8cf6449d2d49e23845",
msg: "MQTT Server Start!",
trigger: "line"
};
client.publish('line/test', JSON.stringify(msg), () => {
//client.end();
});
});
(2).還記得前面我們設定一個主題叫line/test,
EMQX(第5,第10步驟設定呼叫的路由)
對主題(line/test)發送後 就會呼叫我們前面填寫的 sendline
進而轉呼叫line api
// 提供 API 讓外部呼叫 LINE Push
app.post('/sendline', async (req, res) => {
try {
const { to, msg } = req.body;
if (!to || !msg) {
return res.status(400).json({ error: '缺少參數 to 或 msg' });
}
const body = {
to: to,
messages: [{ type: 'text', text: msg }]
};
const response = await axios.post(
'https://api.line.me/v2/bot/message/push',
body,
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${LINE_TOKEN}`
}
}
);
res.json({ success: true, lineResponse: response.data });
} catch (err) {
res.status(500).json({
error: err.response ? err.response.data : err.message
});
}
});